use serde::{Deserialize, Serialize};

#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub enum ResponseType {
    Object,
    List,
    Page
    // 其他可能的枚举值
}

#[derive(Debug, Serialize, Deserialize)]
pub struct ResponseObject<T> {
    pub(crate) response_type: ResponseType,
    pub(crate) code: i32,
    pub(crate) msg: String,
    pub(crate) data: Option<T>,
}

impl<T> ResponseObject<T> {
    pub fn new() -> Self {
        ResponseObject {
            response_type: ResponseType::Object,
            code: 200,
            msg: "success".to_string(),
            data: None,
        }
    }

    pub fn error(code: i32, msg: &str) -> Self {
        ResponseObject {
            response_type: ResponseType::Object,
            code,
            msg: msg.to_string(),
            data: None,
        }
    }

    pub fn error_with_data(code: i32, msg: &str, data: T) -> Self {
        ResponseObject {
            response_type: ResponseType::Object,
            code,
            msg: msg.to_string(),
            data: Some(data),
        }
    }

    pub fn success() -> Self {
        ResponseObject {
            response_type: ResponseType::Object,
            code: 200,
            msg: "success".to_string(),
            data: None,
        }
    }

    pub fn success_with_data(data: T) -> Self {
        ResponseObject {
            response_type: ResponseType::Object,
            code: 200,
            msg: "success".to_string(),
            data: Some(data),
        }
    }

    pub fn set_response_type(&mut self, response_type: ResponseType) {
        self.response_type = response_type;
    }

    pub fn set_code(&mut self, code: i32) {
        self.code = code;
    }

    pub fn set_msg(&mut self, msg: &str) {
        self.msg = msg.to_string();
    }

    pub fn set_data(&mut self, data: T) {
        self.data = Some(data);
    }
}

impl<T: std::fmt::Debug> std::fmt::Display for ResponseObject<T> {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        write!(
            f,
            "ResponseObject(response_type={:?}, code={}, msg={}, data={:?})",
            self.response_type, self.code, self.msg, self.data
        )
    }
}
